# shift

`shift(){:js}` moves the floating element along the specified
axes in order to keep it in view.

Without `shift(){:js}`:

<Chrome>
  <Floating content="Floating wider than its reference">
    <div className="grid place-items-center w-32 h-32 border-2 border-gray-1000 border-dashed" />
  </Floating>
</Chrome>

With `shift(){:js}`:

<Chrome>
  <Floating
    content="Floating wider than its reference"
    middleware={[{name: 'shift'}]}
  >
    <div className="grid place-items-center w-32 h-32 border-2 border-gray-1000 border-dashed" />
  </Floating>
</Chrome>

## Usage

```js
import {computePosition, shift} from '@floating-ui/dom';

computePosition(referenceEl, floatingEl, {
  middleware: [shift()],
});
```

## Options

These are the options you can pass to `shift(){:js}`.

```ts
interface Options extends DetectOverflowOptions {
  mainAxis?: boolean;
  crossAxis?: boolean;
  limiter?: {
    fn: (middlewareArguments: MiddlewareArguments) => Coords;
    options?: any;
  };
}
```

### mainAxis

default: `true{:js}`

This is the main axis in which shifting is applied.

- `x`-axis for `'top'{:js}` and `'bottom'{:js}` placements
- `y`-axis for `'left'{:js}` and `'right'{:js}` placements

```js
shift({mainAxis: false});
```

### crossAxis

default: `false{:js}`

This is the cross axis in which shifting is applied, the opposite
axis of `mainAxis{:.objectKey}`.

Enabling this can lead to the floating element **overlapping**
the reference element, which may not be desired and is often
replaced by the `flip(){:js}` middleware.

```js
shift({crossAxis: true});
```

### limiter

default: no-op

This accepts a function that **limits** the shifting done, in
order to prevent detachment or "overly-eager" behavior. The
behavior is to stop shifting once the opposite edges of the
elements are aligned.

```js
import {shift, limitShift} from '@floating-ui/dom';

shift({limiter: limitShift()});
```

This function itself takes options.

#### limitShift.mainAxis

default: `true{:js}`

Whether to apply limiting on the main axis.

```js
shift({
  limiter: limitShift({mainAxis: false}),
});
```

#### limitShift.crossAxis

default: `true{:js}`

Whether to apply limiting on the cross axis.

```js
shift({
  limiter: limitShift({crossAxis: false}),
});
```

#### limitShift.offset

default: `0{:js}`

This will offset when the limiting starts. A positive number will
start limiting earlier, while negative later.

```js
shift({
  limiter: limitShift({
    // Start limiting 5px earlier
    offset: 5,
  }),
});
```

This can also take a function, which provides the
`Rect{:.class}`s of each element to read their dimensions:

```js
shift({
  limiter: limitShift({
    // Start limiting by the reference's width earlier
    offset: ({reference, floating, placement}) =>
      reference.width,
  }),
});
```

You may also pass an object to configure both axes:

```js
shift({
  limiter: limitShift({
    // object
    offset: {
      mainAxis: 10,
      crossAxis: 5,
    },
    // or a function which returns one
    offset: ({reference, floating, placement}) => ({
      mainAxis: reference.height,
      crossAxis: floating.width,
    }),
  }),
});
```

### ...detectOverflowOptions

All of [detectOverflow](/docs/detectOverflow#options)'s options
can be passed. For instance:

```js
shift({padding: 5}); // 0 by default
```

If you find the padding does not get applied on the right side,
see [Handling large content](/docs/misc#handling-large-content).

## Data

The following data is available in `middlewareData.shift{:js}`:

```js
interface Data {
  x: number;
  y: number;
}
```

`x{:.objectKey}` and `y{:.objectKey}` represent how much the
floating element has been shifted along that axis. The values are
offsets, and therefore can be negative.
